home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et3_0-a1.lha / et3 / src / Data.C < prev    next >
C/C++ Source or Header  |  1992-08-25  |  10KB  |  585 lines

  1. #ifdef __GNUG__
  2. #pragma implementation
  3. #endif
  4.  
  5. #include "Data.h"
  6.  
  7. #include "Class.h"
  8. #include "OrdColl.h"
  9. #include "FileBuf.h"
  10. #include "MemBuf.h"
  11. #include "String.h"
  12. #include "System.h"
  13. #include "ProgressDialog.h"
  14. #include "Directory.h"
  15. #include "Converter.h"
  16.  
  17. enum ePathInfoFlags {
  18.     ePiExec     =   1,
  19.     ePiDir      =   2,
  20.     ePiSpecial  =   4
  21. };
  22.  
  23. //---- bitmap images for file icons --------------------------------------------
  24.  
  25. static u_short DirectoryBits[]= {
  26. #   include "images/directory.image"
  27. };
  28. static u_short ExecBits[]= {
  29. #   include "images/exec.image"
  30. };
  31. static u_short AsciiBits[]= {
  32. #   include "images/ascii.image"
  33. };
  34. static u_short EtBits[]= {
  35. #   include "images/et++.image"
  36. };
  37. static u_short FileBits[]= {
  38. #   include "images/file.image"
  39. };
  40.  
  41. SmartBitmap gETIcon("et.xpm"),            // gETIcon(gPoint16, EtBits),
  42.         gDirectoryIcon("directory.xpm"),    // gDirectoryIcon(gPoint16, DirectoryBits),
  43.         gExecIcon("exec.xpm"),        // gExecIcon(gPoint16, ExecBits),
  44.         gAsciiIcon("ascii.xpm"),        // gAsciiIcon(gPoint16, AsciiBits),
  45.         gFileIcon("file.xpm");        // gFileIcon(gPoint16, FileBits);
  46.         
  47.  
  48. //---- Data --------------------------------------------------------------------
  49.  
  50. NewMetaImpl(Data,Object, (TP(name), T(creator), T(type), TB(isnew), TP(classtype)));
  51.  
  52. Data::Data(bool untitled, char *n)
  53. {
  54.     name= strsave(n);
  55.     isnew= untitled;
  56.     classtype= 0;
  57.     type= cDocTypeUndef;
  58.     creator= cDocCreatorUndef;
  59.     converter= 0;
  60. }
  61.  
  62. Data::~Data()
  63. {
  64.     SafeDelete(name);
  65.     converter= 0;
  66. }
  67.  
  68. bool Data::IsUntitled()
  69. {
  70.     return isnew;
  71. }
  72.  
  73. Symbol Data::Type()
  74. {
  75.     return type;
  76. }
  77.  
  78. Symbol Data::Creator()
  79. {
  80.     return creator;
  81. }
  82.  
  83. int Data::SizeHint()
  84. {
  85.     return -1;
  86. }
  87.  
  88. char *Data::FullName()
  89. {
  90.     return name;
  91. }
  92.  
  93. char *Data::ShortName()
  94. {
  95.     return FullName();
  96. }
  97.  
  98. long Data::UniqueId()
  99. {
  100.     return 0;
  101. }
  102.  
  103. StreamBuf *Data::GetStreamBuf()
  104. {
  105.     return 0;
  106. }
  107.  
  108. static bool forwriting;
  109.  
  110. StreamBuf *Data::GetStreamBufForReading()
  111. {
  112.     forwriting= FALSE;
  113.     StreamBuf *sb= GetStreamBuf();
  114.     forwriting= FALSE;
  115.     sb->seek(0);
  116.     return sb;
  117. }
  118.  
  119. StreamBuf *Data::GetStreamBufForWriting()
  120. {
  121.     forwriting= TRUE;
  122.     StreamBuf *sb= GetStreamBuf();
  123.     forwriting= FALSE;
  124.     return sb;
  125. }
  126.  
  127. long Data::ModifiedAt()
  128. {
  129.     return 0;
  130. }
  131.  
  132. bool gPaste;
  133. static OrdCollection *converters;
  134.  
  135. Object *Data::AsObject(Class *want)
  136. {
  137.     if (gPaste) {
  138.     if (converters == 0)
  139.         converters= new OrdCollection;
  140.     Converter *cv= Converter::FindConverter(this, want, converters);
  141.     if (converters->Size() <= 0)
  142.         SafeDelete(converters);
  143.     converter= 0;
  144.     } else {
  145.     if (converter == 0) {
  146.         if (converters == 0 || converters->Size() <= 0) {
  147.         if (converters == 0)
  148.             converters= new OrdCollection;
  149.         converter= Converter::FindConverter(this, want, converters);
  150.         }
  151.         converter= Converter::SelectConverter(converters);
  152.         SafeDelete(converters);
  153.     }
  154.     if (converter && converter->CanConvert(this, want))
  155.         return converter->Convert(this, want);
  156.     }
  157.     return 0;
  158. }
  159.  
  160. bool Data::FindConvertersFor(Class *w1, Class *w2, Class *w3, Class *w4, Class *w5)
  161. {
  162.     if (w1 && CanConvert(w1))
  163.     return TRUE;
  164.     if (w2 && CanConvert(w2))
  165.     return TRUE;
  166.     if (w3 && CanConvert(w3))
  167.     return TRUE;
  168.     if (w4 && CanConvert(w4))
  169.     return TRUE;
  170.     if (w5 && CanConvert(w5))
  171.     return TRUE;
  172.     return FALSE;
  173. }
  174.  
  175. bool Data::CanConvert(Class *want)
  176. {
  177.     return Converter::FindConverter(this, want) != 0;
  178. }
  179.  
  180. Bitmap *Data::GetBitmap()
  181. {
  182.     return gFileIcon;
  183. }
  184.  
  185. bool Data::IsDirectory()
  186. {
  187.     return FALSE;
  188. }
  189.  
  190. bool Data::IsCCode()
  191. {
  192.     return FALSE;
  193. }
  194.  
  195. bool Data::IsETFormat()
  196. {
  197.     return FALSE;
  198. }
  199.  
  200. bool Data::IsAscii()
  201. {
  202.     return FALSE;
  203. }
  204.  
  205. bool Data::IsValid()
  206. {
  207.     return FALSE;
  208. }
  209.  
  210. bool Data::IsWritable()
  211. {
  212.     return FALSE;
  213. }
  214.   
  215. bool Data::IsReadable()
  216. {
  217.     return FALSE;
  218. }
  219.   
  220. bool Data::IsExecutable()
  221. {
  222.     return FALSE;
  223. }
  224.  
  225. SeqCollection *Data::GetContents()
  226. {
  227.     return 0;
  228. }
  229.  
  230. bool Data::HasContents()
  231. {
  232.     return FALSE;
  233. }
  234.  
  235. Data *Data::GetParent()
  236. {
  237.     return 0;
  238. }
  239.  
  240. OStream& Data::PrintOn(OStream &s)
  241. {
  242.     Object::PrintOn(s);
  243.     s.PrintString(name);
  244.     return s << creator SP << type SP << isnew SP << (long)(classtype) SP
  245.                             << (long)(converter) SP;
  246. }
  247.  
  248. IStream& Data::ReadFrom(IStream &s)
  249. {
  250.     long ct, cv;
  251.     Object::ReadFrom(s);
  252.     SafeDelete(name);
  253.     s.ReadString(&name);
  254.     s >> creator >> type >> isnew >> ct >> cv;
  255.     classtype= (Class*) ct;
  256.     converter= (Converter*) cv;
  257.     return s;
  258. }
  259.  
  260. //---- FileData ----------------------------------------------------------------
  261.  
  262. NewMetaImpl(FileData, Data, (T(sizehint), T(modtime), T(uniqueid), TB(valid)));
  263.  
  264. FileData::FileData(char *nm, bool untitled, bool deep) : Data(untitled)
  265. {
  266.     lookDeep= deep;
  267.     isDeep= 0;
  268.     isAscii= isExec= isDir= FALSE;
  269.     isCCode= isETFormat= FALSE;
  270.     uniqueid= 0;
  271.     sizehint= -1;
  272.     valid= FALSE;
  273.     
  274.     if (nm) {
  275.     if (nm[0] != '/' && !untitled) {
  276.         char *wd= gSystem->WorkingDirectory();
  277.         if (strcmp(nm, ".") == 0)
  278.         name= strsave(wd);
  279.         else {
  280.         if (wd && strcmp(wd, "/"))
  281.             name= strsave(form("%s/%s", wd, nm));
  282.         else
  283.             name= strsave(form("/%s", nm));
  284.         }
  285.     } else
  286.         name= strsave(nm);
  287.     }
  288. }
  289.  
  290. char *FileData::FullName()
  291. {
  292.     return name;
  293. }
  294.     
  295. bool FileData::IsAscii()
  296. {
  297.     WhatType();
  298.     return isAscii;
  299. }
  300.  
  301. bool FileData::IsCCode()
  302. {
  303.     WhatType();
  304.     return isCCode;
  305. }
  306.  
  307. bool FileData::IsETFormat()
  308. {
  309.     if (classtype)
  310.     return TRUE;
  311.     WhatType();
  312.     return isETFormat;
  313. }
  314.  
  315. bool FileData::IsDirectory()
  316. {
  317.     WhatType();
  318.     return isDir;
  319. }
  320.  
  321. bool FileData::IsValid()
  322. {
  323.     return valid;
  324. }
  325.  
  326. bool FileData::IsUntitled()
  327. {
  328.     //return Data::IsUntitled();
  329.     return *FullName() != '/';
  330. }
  331.  
  332. long FileData::ModifiedAt()
  333. {
  334.     WhatType();
  335.     return modtime;
  336. }
  337.  
  338. Symbol FileData::Creator()
  339. {
  340.     WhatType(TRUE);
  341.     return creator;
  342. }
  343.  
  344. bool FileData::IsWritable()
  345. {
  346.     char *nm= FullName();
  347.     if (gSystem->AccessPathName(nm, 0)) {
  348.     char *p= strrchr(nm, '/'), buf[1000];
  349.     if (p) {
  350.         strcpy(buf, nm);
  351.         p= strrchr(buf, '/');
  352.         *p= 0;
  353.     } else
  354.         strcpy(buf, ".");
  355.     nm= buf;
  356.     }
  357.     return !gSystem->AccessPathName(nm, 2);
  358. }
  359.   
  360. bool FileData::IsReadable()
  361. {
  362.     return !gSystem->AccessPathName(FullName(), 4);
  363. }
  364.   
  365. bool FileData::IsExecutable()
  366. {
  367.     WhatType();
  368.     return isExec;
  369. }
  370.  
  371. Bitmap *FileData::GetBitmap()
  372. {
  373.     if (IsDirectory())
  374.     return gDirectoryIcon;
  375.     if (IsExecutable())
  376.     return gExecIcon;
  377.     if (IsCCode()) 
  378.     return gAsciiIcon;
  379.     if (lookDeep) {
  380.     if (IsETFormat())
  381.         return gETIcon;
  382.     if (IsAscii())
  383.         return gAsciiIcon;
  384.     }
  385.     return Data::GetBitmap();
  386. }
  387.  
  388. StreamBuf *FileData::GetStreamBuf()
  389. {
  390.     //StreamBuf *sb= new ProgressFilter;
  391.     //sb->SetBaseStream(new Filebuf(FullName(), forwriting ? output : input));
  392.     //return sb;
  393.     return new Filebuf(FullName(), forwriting ? output : input);
  394. }
  395.  
  396. Symbol FileData::Type()
  397. {
  398.     WhatType(TRUE);
  399.     return type;
  400. }
  401.  
  402. long FileData::UniqueId()
  403. {
  404.     WhatType();
  405.     return uniqueid;
  406. }
  407.  
  408. int FileData::SizeHint()
  409. {
  410.     WhatType();
  411.     return sizehint;
  412. }
  413.  
  414. char *FileData::ShortName()
  415. {
  416.     return BaseName(FullName());
  417. }
  418.  
  419. char *FileData::GetLoadDir()
  420. {
  421.     return gSystem->DirName(FullName());
  422. }
  423.  
  424. void FileData::WhatType(bool deep)
  425. {
  426.     TypeMatcher *tm;
  427.     int flags= 0;
  428.     
  429.     if (isDeep >= 2)
  430.     return;
  431.     
  432.     deep= deep || lookDeep;
  433.     
  434.     if (isDeep == 0) {
  435.     if (gSystem) {
  436.         isDeep= 1;
  437.         valid= gSystem->GetPathInfo(FullName(), &uniqueid, &sizehint, 
  438.                               &flags, &modtime) == 0;
  439.     
  440.         if (flags & ePiDir) {
  441.         isDir= TRUE;
  442.         type= cDocTypeDirectory;
  443.         isDeep= 2;
  444.         return;
  445.         }
  446.         if (flags & ePiSpecial) {
  447.         type= cDocTypeSpecial;
  448.         isDeep= 2;
  449.         return;
  450.         }
  451.         if (flags & ePiExec)
  452.         isExec= TRUE;
  453.     }
  454.     
  455.     tm= TypeMatcher::MatchByName(FullName(), strlen(FullName()));
  456.     if (tm) {
  457.         type= tm->type;
  458.         isAscii= tm->ascii;
  459.         isCCode= tm->isCCode;
  460.         creator= tm->creator;
  461.         isETFormat= tm->isETFormat;
  462.     }
  463.     }
  464.     
  465.     if (!deep)
  466.     return;
  467.  
  468.     if (isDeep > 1)
  469.     return;
  470.     
  471.     isDeep= 2;
  472.     
  473.     tm= TypeMatcher::MatchByContents(FullName());
  474.     if (tm) {
  475.     type= tm->type;
  476.     isAscii= tm->ascii;
  477.     isCCode= tm->isCCode;
  478.     creator= tm->creator;
  479.     isETFormat= tm->isETFormat;
  480.     }
  481. }
  482.  
  483. SeqCollection *FileData::GetContents()
  484. {
  485.     Dir dir(FullName());
  486.     char *nm;
  487.     OrdCollection *files= new OrdCollection;
  488.     
  489.     for (int i= 0; nm= dir(); i++)
  490.     if (strcmp(nm, "."))
  491.         files->Add(new FileData(nm));
  492.     
  493.     return files;
  494. }
  495.  
  496. bool FileData::HasContents()
  497. {
  498.     return IsDirectory();
  499. }
  500.  
  501. Data *FileData::GetParent()
  502. {
  503.     char buf[200], *cp, *fname= FullName();
  504.     if (strcmp(fname, "/") == 0)
  505.     return 0;
  506.     strcpy(buf, fname);
  507.     if (cp= strrchr(buf, '/')) {
  508.     *cp= 0;
  509.     }
  510.     if (cp == buf)
  511.     return new FileData("/");
  512.     return new FileData(buf);
  513. }
  514.  
  515. OStream& FileData::PrintOn(OStream &s)
  516. {
  517.     Data::PrintOn(s);
  518.     return s << sizehint SP << modtime SP << uniqueid SP << valid SP
  519.     << isETFormat SP << isSystem SP << isAscii SP << lookDeep SP
  520.     << isCCode SP << isExec SP << isDeep SP << isDir SP;
  521. }
  522.  
  523. IStream& FileData::ReadFrom(IStream &s)
  524. {
  525.     Data::ReadFrom(s);
  526.     return s >> sizehint >> modtime >> uniqueid >> valid
  527.     >> isETFormat >> isSystem >> isAscii >> lookDeep
  528.     >> isCCode >> isExec >> isDeep >> isDir;
  529. }
  530.  
  531. //---- StreamBufData -----------------------------------------------------------------
  532.  
  533. NewMetaImpl0(StreamBufData,Data);
  534.  
  535. StreamBufData::StreamBufData(StreamBuf *s, const Symbol &t)
  536.                         : Data(FALSE, "streambufdata")
  537. {
  538.     sb= s;
  539.     type= t;
  540. }
  541.  
  542. void StreamBufData::SetType(Symbol t)
  543. {
  544.     type= t;
  545. }
  546.  
  547. int StreamBufData::SizeHint()
  548. {
  549.     return sb->tell();
  550. }
  551.  
  552. StreamBuf *StreamBufData::GetStreamBuf()
  553. {
  554.     return sb;
  555. }
  556.  
  557. //---- ObjectData --------------------------------------------------------------
  558.  
  559. NewMetaImpl0(ObjectData,Data);
  560.  
  561. ObjectData::ObjectData(Object *op) : Data()
  562. {
  563.     object= op;
  564.     classtype= object->IsA();
  565.     type= cDocTypeET;
  566. }
  567.  
  568. ObjectData::~ObjectData()
  569. {
  570.     SafeDelete(object);
  571. }
  572.  
  573. Object *ObjectData::AsObject(Class *want)
  574. {
  575.     if (GetClassType()->isKindOf(want))
  576.     return object->DeepClone();
  577.     return 0;
  578. }
  579.  
  580. bool ObjectData::CanConvert(Class *want)
  581. {
  582.     return GetClassType()->isKindOf(want);
  583. }
  584.  
  585.